package com.jzo2o.health.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.jzo2o.common.expcetions.BadRequestException;
import com.jzo2o.common.expcetions.ForbiddenOperationException;
import com.jzo2o.health.mapper.ReservationSettingMapper;
import com.jzo2o.health.model.domain.Orders;
import com.jzo2o.health.model.domain.ReservationSetting;
import com.jzo2o.health.model.dto.request.ReservationSettingUpsertReqDTO;
import com.jzo2o.health.model.dto.response.ReservationDateResDTO;
import com.jzo2o.health.model.dto.response.ReservationSettingResDTO;
import com.jzo2o.health.service.IOrdersManagerService;
import com.jzo2o.health.service.IReservationSettingService;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.util.List;

@Service
public class ReservationSettingServiceImpl extends ServiceImpl<ReservationSettingMapper, ReservationSetting> implements IReservationSettingService {

    @Resource
    private ReservationSettingMapper reservationSettingMapper;

    @Resource
    private IOrdersManagerService ordersManagerService;

    /**
     * 按月查询预约设置
     *
     * @param date
     * @return
     */
    @Override
    public List<ReservationSettingResDTO> getAdminReservationSettingByMonth(String date) {
        return reservationSettingMapper.getAdminReservationSettingByMonth(date);
    }

    /**
     * 编辑预约设置
     *
     * @param dto
     */
    @Override
    public void editNumberByDate(ReservationSettingUpsertReqDTO dto) {
        // 如果当前时间早于当前系统时间则不处理
        if (dto.getOrderDate().isBefore(LocalDate.now())) {
            throw new BadRequestException("当前时间不允许修改预约人数");
        }

        try {
            // 尝试直接插入新的预约信息，利用唯一约束防止重复插入
            ReservationSetting rs = new ReservationSetting();
            rs.setOrderDate(dto.getOrderDate());
            rs.setNumber(dto.getNumber());
            save(rs);

        } catch (DuplicateKeyException e) {
            // 查询已有的预约信息，由于有唯一约束，这里可以放心地认为只会有一条记录
            ReservationSetting existingRs = lambdaQuery()
                    .eq(ReservationSetting::getOrderDate, dto.getOrderDate())
                    .one();

            // 如果设置的预约人数小于当前已预约的人数则抛异常
            if (dto.getNumber() < existingRs.getReservations()) {
                throw new ForbiddenOperationException("可预约人数不得小于已预约人数");
            }

            // 更新现有预约信息
            boolean update = reservationSettingMapper.updateReservationsNum(dto.getNumber(),dto.getOrderDate());

            if (!update) {
                throw new ForbiddenOperationException("修改【" + dto.getOrderDate() + "】预约人数失败");
            }
        }
    }

    /**
     * 按月查询可预约日期
     *
     * @param month
     * @return
     */
    @Override
    public ReservationDateResDTO getUserReservationDateByMonth(String month) {
        List<String> dateList = reservationSettingMapper.getUserReservationDateByMonth(month);
        return new ReservationDateResDTO(dateList);
    }

    @Override
    public void updateCount(Long id) {
        Orders orders = ordersManagerService.getById(id);
        LocalDate day = orders.getReservationDate();
        reservationSettingMapper.updateCount(day);
    }
}
